package com.qf.service.impl;

import com.qf.dao.*;
import com.qf.pojo.entity.TbAccount;
import com.qf.pojo.entity.TbAdmin;
import com.qf.pojo.entity.TbRole;
import com.qf.pojo.entity.TbUser;
import com.qf.pojo.request.TbAccountReq;
import com.qf.pojo.request.TbAdminReq;
import com.qf.pojo.request.TbAdminRoleReq;
import com.qf.pojo.response.BasePermissionResponse;
import com.qf.pojo.response.BasePermissionValueResponse;
import com.qf.pojo.response.BaseResponse;
import com.qf.service.TbAdminService;
import com.qf.utils.MD5Utils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author xingyu
 */

@Service
public class TbAdminServiceImpl implements TbAdminService {
    @Autowired
    AdminRepository adminRepository;
    @Autowired
    TbAdminRoleRepository tbAdminRoleRepository;
    @Autowired
    TbRoleRepository tbRoleRepository;
    @Autowired
    TbAdminRoleMapper tbAdminRoleMapper;

    /**
     * 查询所有管理员
     *
     * @param page 当前页
     * @param size 当前页显示行数
     * @return 响应对象
     */
    @Override
    public BaseResponse findAll(Integer page, Integer size) {
        PageRequest of = PageRequest.of(page - 1, size);
        Page<TbAdmin> all = adminRepository.findAll(of);
        List<TbAdmin> content = all.getContent();
        long total = all.getTotalElements();
        return new BaseResponse(1, "success", content, total);
    }

    /**
     * 修改或新增管理员
     *
     * @param tbAdminReq 管理员请求对象
     * @return 响应对象
     */
    @Override
    public BaseResponse updateOrSave(TbAdminReq tbAdminReq) {
        TbAdmin tbAdmin = new TbAdmin();
        BeanUtils.copyProperties(tbAdminReq, tbAdmin);
        //需要对前端传过来的参数进行加密处理
        //1.判断前端传来的参数是否经过加密处理,和数据库中的密码进行比较
        String md5 = MD5Utils.CreateMD5(tbAdmin.getAdName(), tbAdmin.getPassword());
        //2.判断轻轻对象的id是否为空,为空表示新增,不为空表示修改
        if (tbAdminReq.getAdId() != null) {
            tbAdmin.setUpdateTime(new Date());
            //通过请求对象的id查询该对象
            Optional<TbAdmin> byId = adminRepository.findById(tbAdminReq.getAdId());
            TbAdmin admin = byId.get();
            //比较前端传入的密码和数据库中的密码
            //如果密码不一致,说明用户修改了密码
            if (!md5.equals(tbAdminReq.getPassword())) {
                tbAdmin.setPassword(md5);
            }
        } else {
            tbAdmin.setCreateTime(new Date());
            //对新增用户密码进行加密
            tbAdmin.setPassword(md5);
        }
        adminRepository.saveAndFlush(tbAdmin);
        return new BaseResponse().SUCCESS();
    }

    /**
     * 根据id删除某个管理员
     *
     * @param adId 管理员id
     * @return 响应对象
     */
    @Override
    public BaseResponse deleteById(Integer adId) {
        adminRepository.deleteById(adId);
        tbAdminRoleRepository.deleteByIdByAdminId(adId);
        return new BaseResponse().SUCCESS();
    }

    /**
     * 根据管理员id查询管理员角色
     * @param adId 管理员id
     * @return 响应对象
     */
    @Override
    public BaseResponse findRoleByAdminId(Integer adId) {
        //1.封装了所有的角色的集合
        //1.1查询数据库中所有的角色
        List<TbRole> all = tbRoleRepository.findAll();
        //1.2建立角色列表,并将数据库中的所有角色放入其中
        List roleList = new ArrayList();
        //1.3放入角色
        for (TbRole list:all) {
            BasePermissionResponse basePermissionResponse = new BasePermissionResponse();
            basePermissionResponse.setKey(list.getRoId());
            basePermissionResponse.setLabel(list.getRoName());
            basePermissionResponse.setDisable(false);
            roleList.add(basePermissionResponse);

        }
        //2.查询该管理员所拥有的所有角色id
        List<Integer> roleId = tbAdminRoleRepository.findRoleIdByAdId(adId);
        //3.将所有的管理员角色以及角色编号放入公共返回值中
        BasePermissionValueResponse basePermissionValueResponse = new BasePermissionValueResponse();
        basePermissionValueResponse.setData(roleList);
        basePermissionValueResponse.setValue(roleId);
        return new BaseResponse(1,"success",basePermissionValueResponse,null);
    }
    /**
     * 修改或新增管理员角色
     * @param tbAdminReq 管理员角色请求对象
     * @return 响应对象
     */
    @Override
    public BaseResponse updateAdminRole(TbAdminRoleReq tbAdminReq) {
        //1.获取管理员id
        Integer adId = tbAdminReq.getAdId();
        //2.获取该管理员对应的所有角色id
        List<Integer> adminRoleIdList = tbAdminReq.getAdminRoleList();
        //3.通过角色对应的管理员id,查询该用户的所有角色
        List<Integer> roleIdByAdId = tbAdminRoleRepository.findRoleIdByAdId(adId);
        //4.进行判断
        if (roleIdByAdId != null){
            //4.1该用户角色列表不为空,则说明该用户拥有角色,我们需将其角色清空
            tbAdminRoleMapper.deleteRoleByAdminId(adId);
        }
        //5.建立新的逻辑,使用动态sql语句修改或新增新的角色(foreach的使用)
        if (adminRoleIdList != null && adminRoleIdList.size()>0){
            tbAdminRoleMapper.addAdminRole(tbAdminReq);
        }
        return new BaseResponse().SUCCESS();
    }

    /**
     * 管理员登录操作
     * @param tbAdminReq 管理员请求对象
     * @return 响应对象
     */
    @Override
    public BaseResponse login(TbAdminReq tbAdminReq) {
        //1.将前台数据传入的用户名和密码放入到UserPasswordToken中
        UsernamePasswordToken admin = new UsernamePasswordToken(tbAdminReq.getAdName(), tbAdminReq.getPassword());
        //2.使用主体进行操作
        Subject subject = SecurityUtils.getSubject();
        try {
            //3.登录
            subject.login(admin);
        } catch (UnknownAccountException unknownAccountException) {
            return new BaseResponse(0,"管理员错误",null,null);
        }catch (IncorrectCredentialsException incorrectCredentialsException){
            return new BaseResponse(0,"密码错误",null,null);
        }
        return new BaseResponse(1,"登录成功!!",admin,null);
    }

}
